package com.xxpay.demo.controllers;

import com.alibaba.fastjson.JSONObject;
import com.xxpay.demo.sdk.PayRequest;
import com.xxpay.demo.util.NumberUtils;
import com.xxpay.demo.util.SignUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.CollectionUtils;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

/**
 * @Auther: xxx
 * @Date: 2019/5/5 13:53
 * @Description:
 */

@Slf4j
@Controller
@RequestMapping("/pay")
public class IndecController {


    @RequestMapping("/index.html")
    public String index(ModelMap model, HttpServletRequest request){
        return "index";
    }

    /***
     * 去下单
     * @param amount
     * @param channelId
     * @return
     */
    @ResponseBody
    @RequestMapping("/payOrder")
    public JSONObject payOrder(String amount,String channelId,HttpServletRequest request) throws Exception{
        String json=PayRequest.payReq(Integer.parseInt(amount),channelId,request);
        return JSONObject.parseObject(json);
    }


    /***
     * 支付成功页面
     * @return
     */
    @RequestMapping("/paySucceed")
    public String paySucceed(ModelMap model, HttpServletRequest request){
        model.put("mchOrderNo",request.getParameter("mchOrderNo"));
        model.put("amount", NumberUtils.divide(new BigDecimal(request.getParameter("amount")),new BigDecimal(100)));
        model.put("mchId",request.getParameter("mchId"));
        return "paySucceed";
    }


    /***
     * 支付宝同步回调成功页面
     * @return
     */
    @RequestMapping("/fxbackurl")
    public String fxbackurl(ModelMap model,HttpServletRequest request){
        log.info("====== ----支付宝同步回调成功页面 ======");
        //获取支付宝POST过来反馈信息
        Map<String,Object> params = new HashMap<String,Object>();
        Map requestParams = request.getParameterMap();
        for (Iterator iter = requestParams.keySet().iterator(); iter.hasNext();) {
            String name = (String) iter.next();
            String[] values = (String[]) requestParams.get(name);
            String valueStr = "";
            for (int i = 0; i < values.length; i++) {
                valueStr = (i == values.length - 1) ? valueStr + values[i]
                        : valueStr + values[i] + ",";
            }
            //乱码解决，这段代码在出现乱码时使用。如果mysign和sign不相等也可以使用这段代码转化
            //valueStr = new String(valueStr.getBytes("ISO-8859-1"), "gbk");
            params.put(name, valueStr);
        }
        //验响应签名
        boolean signResp=SignUtils.verifyPaySign(params,PayRequest.RES_KEY,"payParams");
        log.info("同步回调验签结果signResp={}",signResp);
        log.info("同步回调成功请求数据:params={}", params);
        model.put("mchOrderNo",params.get("mchOrderNo"));
        model.put("mchId",params.get("mchId"));
        model.put("amount", NumberUtils.divide(new BigDecimal(params.get("amount").toString()),new BigDecimal(100)));
        return "paySucceed";
    }


    /***
     * 回调地址
     * @return
     */
    @RequestMapping("/notify.htm")
    public void payNotify(HttpServletRequest request, HttpServletResponse response) throws Exception{
        log.info("====== 开始处理支付中心通知 ======");
        Map<String,Object> paramMap = request2payResponseMap(request, new String[]{
                "payOrderId","mchId","mchOrderNo","channelId","amount","currency","status", "clientIp",
                "device",  "subject", "channelOrderNo", "param1",
                "param2","paySuccTime","backType","sign"
        });
        log.info("支付中心通知请求参数,paramMap={}", paramMap);
        //验响应签名
        boolean signResp=SignUtils.verifyPaySign(paramMap,PayRequest.RES_KEY,"payParams");
        log.info("异步回调验签结果signResp={}",signResp);
        if (!signResp) {
            String errorMessage = "verify request param failed.";
            log.warn(errorMessage);
            outResult(response, "fail");
            return;
        }
        String resStr = "success";
        if(!CollectionUtils.isEmpty(paramMap)){
            //status =2 已支付
            if(paramMap.containsKey("status")&&paramMap.get("status").toString().equals("2")){
                String mchOrderNo=paramMap.get("mchOrderNo").toString();
                String key=String.format("_tem:mchOrderInfo:%s",mchOrderNo);
                JSONObject jsonObject=new JSONObject();
                jsonObject.put("mchOrderNo",mchOrderNo);
                jsonObject.put("amount",paramMap.get("amount").toString());
                jsonObject.put("mchId",paramMap.get("mchId").toString());
            }
        }
        outResult(response, resStr);
        log.info("====== 支付中心通知处理完成 ======");
    }



    void outResult(HttpServletResponse response, String content) throws Exception{
        response.setContentType("text/html");
        PrintWriter pw;
        try {
            pw = response.getWriter();
            pw.print(content);
            log.info("response xxpay complete.");
        } catch (IOException e) {
            log.error("response xxpay write exception.",e);
        }
    }


    public Map<String, Object> request2payResponseMap(HttpServletRequest request, String[] paramArray) {
        Map<String, Object> responseMap = new HashMap<>();
        for (int i = 0;i < paramArray.length; i++) {
            String key = paramArray[i];
            String v = request.getParameter(key);
            if (v != null) {
                responseMap.put(key, v);
            }
        }
        return responseMap;
    }

}
